package jmine.tec.script;

import java.util.Map;

import jmine.tec.utils.Tuple;

/**
 * Interface para ser usada como input da compilacao de um script
 * 
 * @author takeshi
 */
public interface ScriptParameters {

    /**
     * Adiciona um parametro que nao pode ser null e definicao de classe sera dada pelo metodo {@link Object#getClass()}
     * 
     * @param name String
     * @param parameter Object
     */
    void putParameter(String name, Object parameter);

    /**
     * Define um parametro e da o seu valor
     * 
     * @param name String
     * @param parameter Object
     * @param type Class
     */
    void putParameter(String name, Object parameter, Class<?> type);

    /**
     * Define um parametro sem um valor
     * 
     * @param name String
     * @param type Class
     */
    void defineParameter(String name, Class<?> type);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, char value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, byte value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, short value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, int value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, long value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, float value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, double value);

    /**
     * Adiciona uma primitiva como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, boolean value);

    /**
     * Adiciona uma string como uma constante
     * 
     * @param name String o nome da constante
     * @param value o valor
     */
    void putConstant(String name, String value);

    /**
     * Adiciona uma constante que eh um enum
     * 
     * @param <E> o tipo do enum.
     * @param name o nome da constante
     * @param value o valor
     */
    <E extends Enum<?>> void putConstant(String name, E value);

    /**
     * Devolve a lista de valores dos parametros. Modificacoes no mapa nao vao refletir neste {@link ScriptParameters}
     * 
     * @return {@link Map}
     */
    Map<String, Object> getParameterValues();

    /**
     * Devolve a lista de tipos dos parametros. Modificacoes no mapa nao vao refletir neste {@link ScriptParameters}
     * 
     * @return {@link Map}
     */
    Map<String, Class<?>> getParameterDefinitions();

    /**
     * Devolve o mapa de constantes. Modificacoes no mapa nao vao refletir neste {@link ScriptParameters}
     * 
     * @return Map
     */
    Map<String, Object> getConstants();

    /**
     * Devolve a definicao de um parametro. Devolve <code>null</code> se o parametro nao estiver definido
     * 
     * @param name string
     * @return {@link Tuple}
     */
    Tuple<Object, Class<?>> getParameterDefinition(String name);
}
